﻿using System;
using Eneta.Portal.Common;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Publishing;
using Eneta.Portal.Common.Definitions;

namespace Eneta.Portal.Site
{
    public class EnetaProvisioningEngine : SPWebProvisioningProvider
    {
        public override void Provision(SPWebProvisioningProperties props)
        {
            try
            {
                var web = props.Web;
                var lang = props.Web.Language;

                Log("Provision(): Applying site template");
                web.ApplyWebTemplate("Eneta#0");

                Log("Provision(): Ensuring content types");
                EnsureContentTypes(web, PublishingWeb.GetPagesListName(web));

                var role = new SPRoleDefinition();
                role.Name = "authenticated live users";
                web.RoleDefinitions.Add(role);

                Log("Provision(): Adding news site");
                web.Webs.Add("uudised", "Uudised", "Eneta portaali uudised", lang, "News#1", false, false);

                Log("Provisin(): Adding learning site");
                web.Webs.Add("oppimine", Webs.LearningTitle, "Eneta portaali õppimise veeb", lang, "Learning#1", false, false);

                Log("Provision(): Adding events site");
                web.Webs.Add("uritused", "Üritused", "Eneta portaali üritused", lang, "Event#1", false, false);

                Log("Provision(): Adding community site");
                web.Webs.Add("kommuun", "Kommuun", "Eneta portaali kommuun", lang, "Community#1", false, false);

                Log("Provision(): Adding Forum site");
                web.Webs.Add("foorum", "Foorum", "Eneta portaali foorum", lang, "Forum#1", false, false);

                Log("Provision(): Adding admin site");
                web.Webs.Add("admin", "Admin", "Eneta portaali administreerimine", lang, "Enetaadmin#1", false, false);

                Log("Provision(): Adding business site");
                web.Webs.Add("firmad", "Firmad", "Eneta portaali Firmad", lang, "Business#2", false, false);

                Log("Provision(): Updating web");
                web.Update();

                Log("Provision(): Enable Anonymous Access");
                
                web.AnonymousState = SPWeb.WebAnonymousState.On;
                web.AnonymousPermMask64 = SPBasePermissions.ViewListItems | SPBasePermissions.ViewVersions | SPBasePermissions.Open | SPBasePermissions.ViewPages;
                web.Update();

                Log("Provision(): Enable publishing features");
                SetUpPublishingFeatures(web);
                
                Log("Provision(): Provisioning done");
            }
            catch(Exception ex)
            {
                Logger.LogException(ex);
                throw;
            }            
        }

        private void SetUpPublishingFeatures(SPWeb web)
        {
            try
            {
                Logger.LogInfo("SetUpPublishingFeatures(): Creating publishing web", GetType().ToString());
                var pubWeb = PublishingWeb.GetPublishingWeb(web);

                Logger.LogInfo("SetUpPublishingFeatures(): Allowing page layouts", GetType().ToString());
                pubWeb.AllowAllPageLayouts(false);

                Logger.LogInfo("SetUpPublishingFeatures(): Updating publishing web", GetType().ToString());
                pubWeb.Update();

                Logger.LogInfo("SetUpPublishingFeatures(): Publishing features are set", GetType().ToString());
            }
            catch(Exception ex)
            {
                Logger.LogWarning("SetUpPublishingFeatures(): Exception was thrown", GetType().ToString());
                Logger.LogException(ex);
            }
        }

        private void EnsureContentTypes(SPWeb site, string pagesListName) 
        {
            var pageCTs = site.Lists[pagesListName].ContentTypes;
            foreach (SPContentType contentType in site.Site.RootWeb.AvailableContentTypes)
            {
                if (IsCustomContentType(contentType) && pageCTs[contentType.Name] == null)
                    pageCTs.Add(contentType);
            }
        }

        ///<summary> 
        /// Determines whether a given content type is a custom type for this Feature.
        ///</summary> 
        private bool IsCustomContentType(SPContentType contentType)
        {
            if (contentType.Hidden) return false;
            if (contentType.Group.ToUpper() != "Eneta") return false;
            return true;
        }

        private void Log(string message)
        {
            Logger.LogInfo(message, GetType().ToString());
        }
    }
}
